﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ModBot.ConfigBuilder.Providers
{    
    public class HealSettingsProvider
    {
        private ModBotSettingsProvider parentProvider;
        public List<HealSettingInstanceProvider> HealSettingInstances;

        #region Public Properties

        /// <summary>
        /// Gets the number of heal options configured
        /// </summary>
        public int AHCount { get; set; }

        /// <summary>
        /// Gets or sets the interval in seconds to check for heals.
        /// </summary>
        public int AHCheckTime {get;set;}

        /// <summary>
        /// Gets or sets the toggle determining if ModBot will heal
        /// characters outside of Netbots and EQBC. 
        /// ie) Players not running MQ2 or mercenaries.
        /// </summary>
        public Boolean AHHealOOBC { get; set; }

        /// <summary>
        /// Gets or sets a heal loop toggle. This setting
        /// will keep the toon in the heal loop after casting 
        /// Heal# to check for additional heals for the duration of
        /// Timer.
        /// Available options [0,1, off, on|Heal#|Timer]
        /// </summary>
        public string AHHealMode { get; set; }

        /// <summary>
        /// Gets or sets the lowest interuptable spell. 
        /// AHHealSpell1 will never interupt if this
        /// is set to 2.
        /// </summary>
        public int AHInteruptLevel { get; set; }

        /// <summary>
        /// Gets or sets the healing priority order. Modbot will not
        /// interupt healing for a higher priority class to heal that of
        /// a lower class.
        /// </summary>
        public string AHClassPriority { get; set; }

        /// <summary>
        /// Gets or sets the toggle determining if ModBot can
        /// dismount your character to interupt a spell.
        /// </summary>
        public Boolean AHAllowDismount { get; set; }

        #endregion

        private HealSettingsProvider(){}
        public HealSettingsProvider(ModBotSettingsProvider parentProvider)
        {
            this.parentProvider = parentProvider;
            HealSettingInstances = new List<HealSettingInstanceProvider>();
        }

        public override string ToString()
        {
            #region Format String
            string formatString =
                "[AdvHeal]\r\n" +
                "AHCount={0}\r\n" +
                "AHCheckTime={1}\r\n" +
                "AHHealOOBC={2}\r\n" +
                "AHHealMode={3}\r\n" +
                "AHInteruptLevel={4}\r\n" +
                "AHClassPriority={5}\r\n" +
                "AHAllowDismount={6}\r\n\r\n";
                
                
            #endregion


            string output = string.Format(formatString,
                AHCount,
                AHCheckTime,
                AHHealOOBC,
                AHHealMode,
                AHInteruptLevel,
                AHClassPriority,
                AHAllowDismount);

            foreach (HealSettingInstanceProvider provider in this.HealSettingInstances)
            {
                output += provider.ToString();
            }
            

            return output;
        }

        public static HealSettingsProvider LoadFromINI(ModBotSettingsProvider settingsProvider, string filepath)
        {
            HealSettingsProvider provider = new HealSettingsProvider(settingsProvider);

            try
            {
                provider.AHCount = SharedLib.ConvertToInt32(IniFileProvider.ReadValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHCount), Defaults.Default_HealSettings_AHCount);
                provider.AHCheckTime = SharedLib.ConvertToInt32(IniFileProvider.ReadValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHCheckTime), Defaults.Default_HealSettings_AHCheckTime);
                provider.AHHealOOBC = SharedLib.ConvertToBoolean(IniFileProvider.ReadValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHHealOOBC), Defaults.Default_HealSettings_AHHealOOBC);
                provider.AHHealMode = IniFileProvider.ReadValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHHealMode);
                provider.AHInteruptLevel = SharedLib.ConvertToInt32(IniFileProvider.ReadValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHInteruptLevel), Defaults.Default_HealSettings_AHInteruptLevel);
                provider.AHClassPriority = IniFileProvider.ReadValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHClassPriority);
                provider.AHAllowDismount = SharedLib.ConvertToBoolean(IniFileProvider.ReadValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHAllowDismount), Defaults.Default_HealSettings_AHAllowDismount);

                

                provider.HealSettingInstances.Clear();
                for (int i = 0; i < provider.AHCount; i++)
                {
                    HealSettingInstanceProvider instance = HealSettingInstanceProvider.LoadFromINI(provider, i+1, filepath);
                    provider.HealSettingInstances.Add(instance);
                }


                if (provider.AHCount != provider.HealSettingInstances.Count) provider.AHCount = provider.HealSettingInstances.Count;

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return provider;
        }

        public static void SaveToIni(HealSettingsProvider provider, string filepath)
        {
            IniFileProvider.WriteValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHCount, Convert.ToString(provider.AHCount));
            IniFileProvider.WriteValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHCheckTime, Convert.ToString(provider.AHCheckTime));
            IniFileProvider.WriteValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHHealOOBC, Convert.ToString(provider.AHHealOOBC));
            IniFileProvider.WriteValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHHealMode, Convert.ToString(provider.AHHealMode));
            IniFileProvider.WriteValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHInteruptLevel, Convert.ToString(provider.AHInteruptLevel));
            IniFileProvider.WriteValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHClassPriority, Convert.ToString(provider.AHClassPriority));
            IniFileProvider.WriteValue(filepath, Keys.HealSettings_Section_Key, Keys.HealSettings_Key_AHAllowDismount, Convert.ToString(provider.AHAllowDismount));

            for (int i = 0; i < provider.AHCount; i++)
            {
                HealSettingInstanceProvider.SaveToIni(provider.HealSettingInstances[i], filepath);
            }
        }
    }

    public class HealSettingInstanceProvider
    {
        private HealSettingsProvider settingsProvider;
        /// <summary>
        /// Gets or sets the Gem number, alt, ability, item, script, or potionbelt reference to use
        /// for this heal.
        /// </summary>
        public string AHGem { get; set; }

        /// <summary>
        /// Gets or sets the spell, item, alt, ability, or script name to reference with 
        /// this heal.
        /// </summary>
        public string AHSpell { get; set; }

        /// <summary>
        /// Gets or sets the bandolier set name to swap in before casting the heal.
        /// Please see MQ2Bandolier and MQ2Cast for more information.
        /// </summary>
        public string AHSpellFoci { get; set; }

        /// <summary>
        /// Gets or sets any spell extension percentage.
        /// </summary>
        public int AHDurMod { get; set; }

        /// <summary>
        /// Gets or sets the minimum mana percentage to have before
        /// attempting the heal.
        /// </summary>
        public int AHSpellMinMana { get; set; }

        /// <summary>
        /// Gets or sets the alias for the spell being cast. Note this alias
        /// must be unique and cannot contain spaces.
        /// </summary>
        public string AHSpellAlias { get; set; }

        /// <summary>
        /// Gets or sets the channel to announce the heal or, if left blank
        /// will not announce the heal.
        /// </summary>
        public string AHAnnouce { get; set; }

        /// <summary>
        /// Gets or sets the number of targets that must be 
        /// present before casting the spell.
        /// </summary>
        public Int32 AHTarCnt { get; set; }

        /// <summary>
        /// Gets or sets the class or target list for this heal.
        /// Common options:
        /// [pc pet group hp0 war shd pal rng mnk rog brd bst ber shm clr dru wiz mag enc nec tnt mypet self]
        ///     -  pc : include pc's and mercs.
        ///     - group : exclude everyone that is not in group
        ///     - hp0 : set an overall health percentage for any named classes
        ///     - classnames (war, shd, etc.) : used to declare which classes this heal should apply to. Can also be combined with a health persentage (e.g. bst50).
        ///     - mypet to be used by itself (e.g. set up a seperate heal for your pet)
        ///     - tnt : Tankname target. Use for lifetap spells ONLY.
        ///     - self : Only use self if the heal spell is SELF ONLY, or only to be cast on yourself. This setting is exclusive and other targets will not be checked for that spell. 
        /// See the MQ2NetHeal plugin for full options list.
        /// </summary>
        public string AHClass{get;set;}

        /// <summary>
        /// Gets or sets whether pre-condition is set for the heal.
        /// </summary>
        public Boolean AHPreCondition { get; set; }

        /// <summary>
        /// Gets or sets the heal group index.
        /// </summary>
        public int Index { get; set; }

        private HealSettingInstanceProvider() { }

        public HealSettingInstanceProvider(HealSettingsProvider settingsProvider, int index) 
        {
            this.settingsProvider = settingsProvider;
            this.Index = index;

            this.AHGem = Defaults.Default_HealInstance_AHGem;
            this.AHSpell = Defaults.Default_HealInstance_AHSpell;
            this.AHSpellFoci = Defaults.Default_HealInstance_AHSpellFoci;
            this.AHDurMod = Defaults.Default_HealInstance_AHDurMod;
            this.AHSpellMinMana = Defaults.Default_HealInstance_AHSpellMinMana;
            this.AHSpellAlias = Defaults.Default_HealInstance_AHSpellAlias;
            this.AHAnnouce = Defaults.Default_HealInstance_AHAnnouce;
            this.AHTarCnt = Defaults.Default_HealInstance_AHTarCnt;
            this.AHClass = Defaults.Default_HealInstance_AHClass;
            this.AHPreCondition = Defaults.Default_HealInstance_AHPreCondition;
        }

        public override string ToString()
        {
            #region Format String
            string formatString =
                SharedLib.CreateSubCommentBlock("Heal Instance " + Index, SharedLib.NewLine, true) +                 
                "AHGem{0}={1}\r\n" +
                "AHSpell{0}={2}\r\n" +
                "AHSpellFoci{0}={3}\r\n" +
                "AHDurMod{0}={4}\r\n" +
                "AHSpellMinMana{0}={5}\r\n" +
                "AHSpellAlias{0}={6}\r\n" +
                "AHAnnouce{0}={7}\r\n" +
                "AHTarCnt{0}={8}\r\n" +
                "AHClass{0}={9}\r\n" +
                "AHPreCondition{0}={10}\r\n\r\n";
                
            #endregion


            string output = string.Format(formatString,
                Index,
                AHGem,
                AHSpell,
                AHSpellFoci,
                AHDurMod,
                AHSpellMinMana,
                AHSpellAlias,
                AHAnnouce,
                AHTarCnt,
                AHClass,
                AHPreCondition);

            return output;
        }

        public static HealSettingInstanceProvider LoadFromINI(HealSettingsProvider settingsProvider, int index, string filepath)
        {
            HealSettingInstanceProvider provider = new HealSettingInstanceProvider(settingsProvider, index);

            try
            {
                provider.AHGem = IniFileProvider.ReadValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHGem + provider.Index);
                provider.AHSpell = IniFileProvider.ReadValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHSpell + provider.Index);
                provider.AHSpellFoci = IniFileProvider.ReadValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHSpellFoci + provider.Index);
                provider.AHDurMod = SharedLib.ConvertToInt32(IniFileProvider.ReadValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHDurMod + provider.Index), Defaults.Default_HealInstance_AHDurMod);
                provider.AHSpellMinMana = SharedLib.ConvertToInt32(IniFileProvider.ReadValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHSpellMinMana + provider.Index), Defaults.Default_HealInstance_AHSpellMinMana);
                provider.AHSpellAlias = IniFileProvider.ReadValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHSpellAlias + provider.Index);
                provider.AHAnnouce = IniFileProvider.ReadValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHAnnouce + provider.Index);
                provider.AHTarCnt = SharedLib.ConvertToInt32(IniFileProvider.ReadValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHTarCnt + provider.Index), Defaults.Default_HealInstance_AHTarCnt);
                provider.AHClass = IniFileProvider.ReadValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHClass + provider.Index);
                provider.AHPreCondition = SharedLib.ConvertToBoolean(IniFileProvider.ReadValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHPreCondition + provider.Index), Defaults.Default_HealInstance_AHPreCondition);               
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return provider;
        }

        public static void SaveToIni(HealSettingInstanceProvider provider, string filepath)
        {
            IniFileProvider.WriteValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHGem + provider.Index, Convert.ToString(provider.AHGem));
            IniFileProvider.WriteValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHSpell + provider.Index, Convert.ToString(provider.AHSpell));
            IniFileProvider.WriteValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHSpellFoci + provider.Index, Convert.ToString(provider.AHSpellFoci));
            IniFileProvider.WriteValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHDurMod + provider.Index, Convert.ToString(provider.AHDurMod));
            IniFileProvider.WriteValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHSpellMinMana + provider.Index, Convert.ToString(provider.AHSpellMinMana));
            IniFileProvider.WriteValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHSpellAlias + provider.Index, Convert.ToString(provider.AHSpellAlias));
            IniFileProvider.WriteValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHAnnouce + provider.Index, Convert.ToString(provider.AHAnnouce));
            IniFileProvider.WriteValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHTarCnt + provider.Index, Convert.ToString(provider.AHTarCnt));
            IniFileProvider.WriteValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHClass + provider.Index, Convert.ToString(provider.AHClass));
            IniFileProvider.WriteValue(filepath, Keys.HealInstance_Section_Key, Keys.HealInstance_Key_AHPreCondition + provider.Index, Convert.ToString(provider.AHPreCondition));
        }
    }
}
